package cn.jsu.oj.dispatchServer.net;

import cn.jsu.oj.dispatchServer.config.ResourceConfig;
import cn.jsu.oj.dispatchServer.pojo.AbstractPack;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.nio.ByteBuffer;
import java.util.List;

/**
 * @author ahtonc
 */
//ByteToMessageDecoder是一种ChannelInboundHandler，可以称为解码器，负责将byte字节流住(ByteBuf)转换成一种Message，Message是应用可以自己定义的一种Java对象。
//ChannelInboundHandler(入站)

public class InBoundHandle extends ByteToMessageDecoder {

    public static int BASE_LENGTH = ResourceConfig.getConfigInteger("parsing.pack.length",7);
    public static String HEAD_DATA = ResourceConfig.getConfigString("parsing.pack.head","jsu");

    /**
     * netty读包规则
     * @param channelHandlerContext
     * @param byteBuf
     * @param list
     * @throws Exception
     */
    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        //分配字节缓冲区
        ByteBuffer bf = ByteBuffer.allocate(1024 * 4);
        //可读长度必须大于基本长度
        if (byteBuf.readableBytes() >= BASE_LENGTH) {
            // 记录包头开始的index
            int beginReader;
            while (true) {
                // 获取包头开始的index
                beginReader = byteBuf.readerIndex();
                // 标记包头开始的index
                byteBuf.markReaderIndex();
//                int headLength = byteBuf.readInt();
//                if (headLength > 0 && headLength < BASE_LENGTH) {
                    byte[] result = new byte[3];
                    byteBuf.readBytes(result);

                    // 读到了协议的开始标志，结束while循环
                    if (HEAD_DATA.equals(new String(result, "UTF-8"))) {
                        break;
                    }
//                }
                // 未读到包头，略过一个字节,每次略过，一个字节，去读取，包头信息的开始标记
                byteBuf.resetReaderIndex();
                byteBuf.readByte();
                // 当略过，一个字节之后，数据包的长度，又变得不满足,此时，应该结束。等待后面的数据到达
                if (byteBuf.readableBytes() < BASE_LENGTH) {
                    return;
                }
            }
            // 消息的长度
            int length = byteBuf.readInt();

            // 判断请求数据包数据是否到齐
            if (byteBuf.readableBytes() < length) {
                // 还原读指针
                byteBuf.readerIndex(beginReader);
                return;
            }
            // 读取data数据
            byte[] data = new byte[length];
            byteBuf.readBytes(data);

            AbstractPack pack = AbstractPack.deserialize(data);
//            System.out.println(pack);
            list.add(pack);
        }
    }
}